package com.hmkj.web.controller.trade;

import com.hmkj.common.entity.ResultEntity;
import com.hmkj.common.page.BasePageParams;
import com.hmkj.common.page.Pages;
import com.hmkj.common.utils.BigDecimalUtil;
import com.hmkj.common.utils.DateUtils;
import com.hmkj.common.utils.PriceHelper;
import com.hmkj.core.constant.ConfigNID;
import com.hmkj.core.eolinker.endpoints.QuotationEndpoint;
import com.hmkj.core.eolinker.models.ModelRealTime;
import com.hmkj.core.exception.BussinessException;
import com.hmkj.core.mapper.order.OrderMapper;
import com.hmkj.core.model.order.OrderModel;
import com.hmkj.core.po.order.Order;
import com.hmkj.core.po.simulation.OrderSimulation;
import com.hmkj.core.po.user.User;
import com.hmkj.core.service.order.OrderOperationService;
import com.hmkj.core.service.order.OrderService;
import com.hmkj.core.service.userFreeze.UserFreezeService;
import com.hmkj.web.controller.GenericController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.web.bind.annotation.*;
import sun.security.krb5.Config;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ......................我佛慈悲......................
 * ......................_oo0oo_.......................
 * .....................o8888888o......................
 * .....................88" . "88......................
 * .....................(| -_- |)......................
 * .....................0\  =  /0......................
 * ...................___/`---'\___....................
 * ..................' \\|     |// '...................
 * ................/ \\|||  :  |||// \.................
 * .............../ _||||| -卍-|||||- \................
 * ..............|   | \\\  -  /// |   |...............
 * ..............| \_|  ''\---/''  |_/ |...............
 * ..............\  .-\__  '-'  ___/-. /...............
 * ............___'. .'  /--.--\  `. .'___.............
 * .........."" '<  `.___\_<|>_/___.' >' ""............
 * ........| | :  `- \`.;`\ _ /`;.`/ - ` : | |.........
 * ........\  \ `_.   \_ __\ /__ _/   .-` /  /.........
 * ....=====`-.____`.___ \_____/___.-`___.-'=====......
 * ......................`=---='.......................
 * ....................................................
 * .................佛祖开光 ,永无BUG...................
 */
@Api(description = "点卖")
@Slf4j
@RestController
@RequestMapping(GenericController.MEMBER_URL + "/trade/sell")
public class AppSellController extends GenericController<Integer, Order> {

    @Resource
    private OrderService orderService;

    @ApiOperation(value = "点卖列表", notes = "点卖列表")
    @RequestMapping(value = "/sellList", method = RequestMethod.POST)
    @ResponseBody
    public ResultEntity sellList(@ApiParam("类型 1(匹配,交易) 2(持仓,待平仓,平仓中) 3(待结算,已结算,流单)") @RequestParam(required = true) Integer type,
                                 @ModelAttribute BasePageParams basePageParams) throws Exception {
        User user = getLoginUser();
        //持仓中，待平仓 平仓中 待结算 的订单
        Map<String, Object> param = new HashMap<>();
        param.put("userId", user.getId());
        if (null == type) {
            throw new Exception("请输入类型");
        }
        param.put("type", type);
        param.put("basePageParams", basePageParams);
        Pages<OrderModel> pages = orderService.selectByPage(basePageParams,
                q -> ((OrderMapper) q).findCountForOrder(param),
                q -> ((OrderMapper) q).findListForOrder(param));
        List<OrderModel> orderList = pages.getRows();
        if (CollectionUtils.isNotEmpty(orderList)) {
            for (OrderModel order : orderList) {
                ModelRealTime realTime = QuotationEndpoint.realtime(order.getEquityCode());
                order.setLastPrice(realTime.getLast_price());
                if (order.getStatus() == Order.STATUS.T3.code) {
                    String lastPrice = realTime.getLast_price();
                    BigDecimal buyDealPrice = order.getBuyDealPrice();
                    BigDecimal dealNumber = BigDecimal.valueOf(order.getBuyDealNumber());
                    //盈亏
                    String profit = String.valueOf(BigDecimalUtil.mul(BigDecimalUtil.sub(Double.parseDouble(lastPrice), buyDealPrice.doubleValue()), dealNumber.doubleValue()));
                    order.setProfit(profit);
                    //判断是否是单日的订单
                    Order o = orderService.selectByPrimaryKey(order.getId());
                    if (DateUtils.secondBetween(DateUtils.getTodayZero(), o.getBuyTime()) > 0) {
                        //当天订单，不能点卖
                        order.setStatus(9);
                    }
                }
                if (order.getStatus() == Order.STATUS.T1.code || order.getStatus() == Order.STATUS.T2.code) {
                    order.setBuyDealPrice(order.getBuyPrice());
                    order.setBuyDealNumber(order.getBuyNumber());
                    order.setBuyDealTime(order.getCreateTime());
                }
                //交易分配，盈利总额 * 盈利分配
                if (order.getStatus() == Order.STATUS.T7.code) {
                    BigDecimal totalProfit = order.getProfitCount();
                    BigDecimal scale = order.getDivideScale();
                    if (PriceHelper.isLessThan(totalProfit, BigDecimal.ZERO)) {
                        order.setTradeProfit(BigDecimal.ZERO.toString());
                    } else {
                        order.setTradeProfit(BigDecimalUtil.round(String.valueOf(totalProfit.multiply(scale)), 2).toString());
                    }
                }
//                order.setStopLossLine(PriceHelper.format(order.getStopLossLine(), 0));
            }
        }
        //计算持仓盈亏
        double total = holdingProfit(user.getId());
        pages.setRows(orderList);
        return ok(m -> {
            m.put("data", pages);
            m.put("totalProfit", total);
        });
    }


    @ApiOperation(value = "平仓", notes = "平仓")
    @RequestMapping(value = "/toSell", method = RequestMethod.POST)
    @ResponseBody
    public ResultEntity toSell(@ApiParam("订单Id") @RequestParam(required = true) Integer id) throws Exception {
        User user = getLoginUser();
        if (null == id) {
            throw new BussinessException("参数有误");
        }
        orderService.toCover(id,user);
        //计算持仓盈亏
        double total = holdingProfit(user.getId());
        return ok(total);
    }

    @ApiOperation(value = "点卖明细", notes = "点卖明细")
    @RequestMapping(value = "/detailJson", method = RequestMethod.POST)
    @ResponseBody
    public ResultEntity sellDetail(@Param("id") @RequestParam(required = true) Integer id) throws Exception {
        if (null == id) {
            throw new BussinessException("参数有误");
        }
        Order order = orderService.selectByPrimaryKey(id);
        if (null == order) {
            throw new BussinessException("订单不存在");
        }
        return ok(order);
    }

    @ApiOperation(value = "修改止损", notes = "修改止损")
    @RequestMapping(value = "/modifyStopLoss", method = RequestMethod.POST)
    @ResponseBody
    public ResultEntity modifyStopLoss(@ApiParam("id") @RequestParam(required = true) Integer id,
                                        @ApiParam("止损价格") @RequestParam(required = true) BigDecimal stopLosePrice,
                                        @ApiParam("需要追加的保证金") @RequestParam(required = true) BigDecimal needDeposit) throws Exception {
        if (null == id) {
            throw new BussinessException("参数有误");
        }
        if (stopLosePrice == null || PriceHelper.isLessThanOrEquals(stopLosePrice, BigDecimal.ZERO)) {
            throw new BussinessException("请填写止损价格");
        }
        if (needDeposit == null || PriceHelper.isLessThan(needDeposit, BigDecimal.ZERO)) {
            throw new BussinessException("需要追加的保证金参数有误");
        }
        Order order = orderService.selectByPrimaryKey(id);
        if (null == order) {
            throw new BussinessException("订单不存在");
        }
        if (order.getStatus() != Order.STATUS.T3.code) {
            throw new BussinessException("订单状态已改变，请刷新");
        }
        ModelRealTime modelRealTime = QuotationEndpoint.realtime(order.getEquityCode());
        if (null == modelRealTime) {
            throw new BussinessException("股票信息出错");
        }
        orderService.doModifyStopLoss(order, stopLosePrice,needDeposit,new BigDecimal(modelRealTime.getLast_price()));
        return ok("修改止损成功",ResultEntity.SUCCESS);
    }

//    @ApiOperation(value = "补亏", notes = "补亏")
//    @RequestMapping(value = "/repairLoss", method = RequestMethod.POST)
//    @ResponseBody
//    public ResultEntity repairLoss(@ApiParam("id") @RequestParam(required = true) Integer id,
//                                   @ApiParam("补亏金额") @RequestParam(required = true) BigDecimal repair) throws Exception {
//        if (null == id) {
//            throw new BussinessException("参数有误");
//        }
//        if (repair == null || PriceHelper.isLessThanOrEquals(repair, BigDecimal.ZERO)) {
//            throw new BussinessException("请填写补亏金额");
//        }
//        Order order = orderService.selectByPrimaryKey(id);
//        if (null == order) {
//            throw new BussinessException("订单不存在");
//        }
//        if (order.getStatus() != Order.STATUS.T3.code) {
//            throw new BussinessException("订单状态已改变，请刷新");
//        }
//        orderService.doRepairLoss(order, repair);
//        return ok("补亏成功");
//    }

    /**
     * 计算持仓盈亏
     *
     * @param userId
     * @return
     * @throws Exception
     */
    public double holdingProfit(Integer userId) throws Exception {
        //计算持仓盈亏
        double total = 0;
        List<Order> orders = orderService.select(new Order(t -> {
            t.setUserId(userId);
            t.setStatus(Order.STATUS.T3.code);
        }));
        if (CollectionUtils.isNotEmpty(orders)) {
            for (Order order : orders) {
                ModelRealTime realTime = QuotationEndpoint.realtime(order.getEquityCode());
                String lastPrice = realTime.getLast_price();
                BigDecimal buyDealPrice = order.getBuyDealPrice();
                BigDecimal dealNumber = BigDecimal.valueOf(order.getBuyDealNumber());
                //盈亏
                String profit = String.valueOf(BigDecimalUtil.mul(BigDecimalUtil.sub(Double.parseDouble(lastPrice), buyDealPrice.doubleValue()), dealNumber.doubleValue()));
                total = total + Double.parseDouble(profit);
            }
        }
        return total;
    }

}
